package com.afdor.rws.test.event.driven;

import com.afdor.rws.core.extension.ExtensionLoader;
import com.afdor.rws.core.extension.spring.annotation.ExtensionComponentScan;
import com.afdor.rws.event.Event;
import com.afdor.rws.event.EventBus;
import com.afdor.rws.event.EventSource;
import com.afdor.rws.event.autoconfigure.annotation.EnableEventBus;
import com.afdor.rws.event.autoconfigure.listener.EventBusApplicationLoadedListener;
import com.afdor.rws.event.channel.ChannelProvider;
import com.afdor.rws.event.channel.aliyun.mq.AliyunMQChannelProvider;
import com.afdor.rws.event.config.EventConfig;
import com.afdor.rws.event.config.EventConfigUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.env.Environment;

import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;

/**
 * 启动类
 *
 * @author 悭梵
 * @date Created in 2018-08-21 16:29
 */
@Slf4j
@EnableEventBus
@SpringBootApplication
@ExtensionComponentScan("com.afdor.rws.test.event.driven")
@ComponentScans({
        @ComponentScan("com.afdor.rws.test.event.driven.configation")
})
public class Application implements EventBusApplicationLoadedListener {

    private LongAdder longAdder = new LongAdder();
    private static final long allSize = 100;
    private static long startTime = -1L;


    public static void main(String[] args) {
        System.setProperty(EventConfigUtils.EVENT_STRATEGY_NAME_ID, "springUuid");

        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

        EventBus eventBus = context.getBean(EventBus.class);
        String eventSourceName = "spring.boot.test.event";

        ExecutorService executorService = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
        startTime = System.currentTimeMillis();
        for (int i = 1; i < allSize; i++) {
            int idx = i;
            executorService.submit(() -> {
                try {
                    eventBus.sendAndCommitEvent(new Event.EventBuilder<HashMap<String, String>>()
                            .eventSourceName(eventSourceName)
                            .source(new HashMap<String, String>() {
                                {
                                    put("key", RandomStringUtils.randomAlphanumeric(1024));
                                }
                            })
                            .build());
                    log.info("===============> 生成第" + idx + "条消息");
                } catch (Exception e) {
                    log.error("", e);
                }
            });
        }

    }

    @Override
    public void onLoaded(EventBus defaultEventBus, ChannelProvider defaultChannelProvider) {
        String eventSourceName = "spring.boot.test.event";
        defaultEventBus.getEventSourceManager().addEventSource(ExtensionLoader
                .getInstance(EventSource.class)
                .newExtensionOrDefault(EventConfigUtils.getProperty(EventConfigUtils.EVENT_SOURCE_NAME))
                .setEventSourceName(eventSourceName)
                .setChannelProvider(defaultChannelProvider));

        defaultEventBus.registerHandler(eventSourceName, event -> {
            longAdder.add(1L);
            log.info("<=============== " + longAdder.longValue() + " : " + JSON.toJSONString(event));
            if (longAdder.longValue() == allSize) {
                log.info("共用时：" + ((System.currentTimeMillis() - startTime) / 1000) + "秒");
                System.exit(0);
            }
        });
    }


    /**
     * 事件相关配置初始化
     *
     * @param environment
     * @return
     */
    @Bean
    @DependsOn("globalEventConfig")
    public EventConfig aliyunMnsEventConfig(Environment environment) {
        EventConfig eventConfig = new EventConfig();
        // 阿里云账户标识
        eventConfig.setProperty(AliyunMQChannelProvider.ALIYUN_MQ_SECRET_ID, environment.getProperty(AliyunMQChannelProvider.ALIYUN_MQ_SECRET_ID));
        // MNS API秘钥
        eventConfig.setProperty(AliyunMQChannelProvider.ALIYUN_MQ_SECRET_KEY, environment.getProperty(AliyunMQChannelProvider.ALIYUN_MQ_SECRET_KEY));
        // MNS的接入地址
        eventConfig.setProperty(AliyunMQChannelProvider.ALIYUN_MQ_ENDPOINT, environment.getProperty(AliyunMQChannelProvider.ALIYUN_MQ_ENDPOINT));
        // 全局配置
        EventConfigUtils.setGlobalConfig(eventConfig);
        return eventConfig;
    }


}
